import axios from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getToken, clearAuth } from './auth'
import router from '@/router'
import { getAuthConfig } from '@/config/auth.config'

// 获取统一认证配置
const authConfig = getAuthConfig()

/**
 * 创建统一的Axios请求实例工厂
 * @param {Object} options - 配置选项
 * @returns {AxiosInstance} - 配置好的axios实例
 */
export function createRequestInstance(options = {}) {
  const {
    baseURL = window.__APP_CONFIG?.API_BASE_URL || '', // 使用外部配置的API地址
    timeout = 200000,
    withCredentials = true,
    isClient = false, // 是否是客户端模式
    useElementUI = true, // 是否使用ElementUI的消息提示
    redirectOnAuthFail = true, // 认证失败时是否自动跳转
    redirectPath = authConfig.CLIENT_LOGIN_PATH, // 认证失败后的跳转路径
    autoLogoutTime = authConfig.AUTO_LOGOUT_TIME, // 自动登出时间
    tokenPrefix = authConfig.TOKEN_PREFIX, // token前缀
    tokenKey = authConfig.TOKEN_KEY, // localStorage中token的key
    getTokenFn = null, // 自定义获取token的函数
    clearAuthFn = null, // 自定义清除认证的函数
    routerInstance = null, // 自定义路由实例
    debug = authConfig.DEBUG_ENABLED, // 是否开启调试模式
    setupActivityMonitor = true, // 是否设置活动监听器
  } = options

  // 使用提供的函数或默认函数
  const getTokenFunction = getTokenFn || (() => localStorage.getItem(tokenKey))
  const clearAuthFunction = clearAuthFn || (() => localStorage.removeItem(tokenKey))
  const routerObj = routerInstance || router

  // 创建axios实例
  const service = axios.create({
    baseURL,
    timeout,
    withCredentials,
  })

  /**
   * 日志函数
   */
  const log = {
    info: (...args) => {
      if (debug) console.log(`[${isClient ? 'Client' : 'Admin'}]`, ...args)
    },
    error: (...args) => console.error(`[${isClient ? 'Client' : 'Admin'}]`, ...args),
    warn: (...args) => console.warn(`[${isClient ? 'Client' : 'Admin'}]`, ...args),
  }

  // 请求拦截器
  service.interceptors.request.use(
    (config) => {
      try {
        // 添加时间戳避免缓存，解决重复导航不发送请求问题
        if (config.method.toLowerCase() === 'get') {
          config.params = {
            ...config.params,
            _t: Date.now(),
          }
        }

        // 添加token到请求头
        const token = getTokenFunction()
        if (token) {
          config.headers['Authorization'] = `${tokenPrefix}${token}`
          try {
            const userInfo = JSON.parse(localStorage.getItem('user_info'))
            if (userInfo && userInfo.username) {
              config.headers['username'] = userInfo.username
            }
          } catch (e) {
            log.warn('获取用户信息失败', e)
          }
        }

        // 确保URLSearchParams对象被正确处理
        if (config.data instanceof URLSearchParams) {
          config.data = config.data.toString()
          config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
        }

        log.info('发送请求:', config.url, config.params)
        return config
      } catch (err) {
        log.error('请求拦截器出错:', err)
        return config
      }
    },
    (error) => {
      log.error('请求错误:', error)
      return Promise.reject(error)
    },
  )

  // 响应拦截器
  service.interceptors.response.use(
    (response) => {
      try {
        log.info('接收响应:', response.config.url, response.status)

        // 如果是流式响应，直接返回response对象
        if (response.headers['content-type']?.includes('text/event-stream')) {
          return response
        }

        // 确保 response.data 存在，避免空对象引起的错误
        const res = response.data || {}

        // FastAPI的JWT登录直接返回token数据，不需要判断code
        if (response.config.url.includes('/auth/jwt/login')) {
          return res
        }

        // 检查是否返回了Unauthorized
        if (res && res.detail === 'Unauthorized') {
          log.warn('检测到Unauthorized响应', res)

          if (useElementUI) {
            ElMessage({
              message: '登录已过期，请重新登录',
              type: 'error',
              duration: 5 * 1000,
            })
          }

          // 清除登录信息并跳转到登录页
          clearAuthFunction()

          if (redirectOnAuthFail) {
            const targetPath = isClient
              ? redirectPath
              : `${redirectPath}?redirect=${encodeURIComponent(routerObj.currentRoute.value.fullPath)}`

            window.location.href = targetPath
          }

          return Promise.reject(new Error('Unauthorized'))
        }

        // 修改：所有2xx状态码都视为成功
        if (response.status >= 200 && response.status < 300) {
          // 成功响应，直接返回数据
          return res
        } else {
          // 非2xx状态码处理
          const message = res.message || res.detail || `请求失败，状态码: ${response.status}`

          if (useElementUI) {
            ElMessage({
              message,
              type: 'error',
              duration: 5 * 1000,
            })
          }

          // 处理特定错误码
          if (response.status === 401 && useElementUI && redirectOnAuthFail) {
            // 未授权，重新登录
            ElMessageBox.confirm('登录状态已过期，您可以继续留在该页面，或者重新登录', '系统提示', {
              confirmButtonText: '重新登录',
              cancelButtonText: '取消',
              type: 'warning',
            }).then(() => {
              clearAuthFunction()
              const targetPath = isClient
                ? redirectPath
                : `${redirectPath}?redirect=${encodeURIComponent(routerObj.currentRoute.value.fullPath)}`

              if (isClient) {
                window.location.href = targetPath
              } else {
                routerObj.push(targetPath)
              }
            })
          }

          return Promise.reject(new Error(message))
        }
      } catch (err) {
        log.error('响应拦截器出错:', err)
        return Promise.reject(err)
      }
    },
    (error) => {
      try {
        log.error('响应错误:', error.message, error.config?.url)

        // 判断是否请求超时
        if (error.code === 'ECONNABORTED' && error.message.includes('timeout')) {
          const message = '请求超时，请稍后重试'
          if (useElementUI) {
            ElMessage({
              message,
              type: 'error',
              duration: 5 * 1000,
            })
          }
          return Promise.reject(new Error(message))
        }

        let message = '网络错误，请稍后重试'

        if (error.response) {
          const errorData = error.response.data || {}
          log.error('错误数据:', errorData)

          // 检查特定的Unauthorized响应
          if (errorData.detail === 'Unauthorized') {
            message = '登录已过期，请重新登录'
            // 清除登录信息并跳转到登录页
            clearAuthFunction()

            if (redirectOnAuthFail) {
              const targetPath = isClient
                ? redirectPath
                : `${redirectPath}?redirect=${encodeURIComponent(routerObj.currentRoute.value.fullPath)}`

              if (isClient) {
                window.location.href = targetPath
              } else {
                routerObj.push(targetPath)
              }
            }

            return Promise.reject(new Error(message))
          }

          switch (error.response.status) {
            case 401:
              message = '未授权，请重新登录'
              // 清除登录信息并跳转到登录页
              clearAuthFunction()

              if (redirectOnAuthFail) {
                const targetPath = isClient
                  ? redirectPath
                  : `${redirectPath}?redirect=${encodeURIComponent(routerObj.currentRoute.value.fullPath)}`

                if (isClient) {
                  window.location.href = targetPath
                } else {
                  routerObj.push(targetPath)
                }
              }
              break
            case 403:
              message = '拒绝访问'
              break
            case 404:
              message = '请求的资源不存在'
              break
            case 422:
              message = '参数验证错误: ' + JSON.stringify(errorData)
              break
            case 500:
              message = '服务器错误'
              break
            default:
              message = `请求失败: ${error.response.status}`
          }

          if (errorData.detail === 'LOGIN_BAD_CREDENTIALS') {
            message = '用户名或密码不正确，请重新输入'
          } else if (errorData.detail) {
            message = `${message}，错误详情: ${errorData.detail}`
          }
        } else if (error.request) {
          // 请求已发出，但没有收到响应
          message = '服务器无响应，请稍后重试'
        }

        if (useElementUI) {
          ElMessage({
            message,
            type: 'error',
            duration: 5 * 1000,
          })
        }

        return Promise.reject(new Error(message))
      } catch (err) {
        log.error('错误处理过程中出错:', err)
        return Promise.reject(error)
      }
    },
  )

  // 添加用户活动监听（如果设置了setupActivityMonitor并且autoLogoutTime大于0）
  // 使用全局标志避免重复设置监听器
  if (setupActivityMonitor && autoLogoutTime > 0 && typeof window !== 'undefined') {
    // 检查全局监听器是否已经设置
    if (!window.__activityMonitorSetup) {
      log.info('设置用户活动监听器，超时时间:', autoLogoutTime / 1000, '秒')

      let userActivityTimeout

      function resetUserActivityTimer() {
        clearTimeout(userActivityTimeout)
        userActivityTimeout = setTimeout(() => {
          // 检查token
          const token = getTokenFunction()
          if (token) {
            // 发送请求验证token
            // log.info('发送token验证请求到:', verifyTokenURL)
            // service.get(verifyTokenURL).catch((err) => {
            //   log.warn('Token验证失败:', err)
            //   clearAuthFunction()
            //   if (redirectOnAuthFail) {
            //     window.location.href = redirectPath
            //   }
            // })
          }
        }, autoLogoutTime)
      }

      // 注册事件监听器
      window.addEventListener('mousemove', resetUserActivityTimer)
      window.addEventListener('keypress', resetUserActivityTimer)
      window.addEventListener('click', resetUserActivityTimer)
      window.addEventListener('scroll', resetUserActivityTimer)

      // 设置全局标志，防止重复添加监听器
      window.__activityMonitorSetup = {
        timeoutValue: autoLogoutTime,
        resetTimer: resetUserActivityTimer,
        initialized: Date.now(),
      }

      // 初始化计时器
      resetUserActivityTimer()

      log.info('用户活动监听器设置完成')
    } else {
      // 已经存在监听器，更新超时时间（如果新值更短）
      if (autoLogoutTime < window.__activityMonitorSetup.timeoutValue) {
        log.info('更新现有活动监听器的超时时间:', autoLogoutTime / 1000, '秒')
        window.__activityMonitorSetup.timeoutValue = autoLogoutTime
        // 重置计时器
        window.__activityMonitorSetup.resetTimer()
      }
    }
  }

  return service
}

/**
 * 创建一个enhancedFetch工具
 * @param {Object} options - 配置选项
 * @returns {Function} - 增强的fetch函数
 */
export function createEnhancedFetch(options = {}) {
  const {
    baseURL = '',
    timeout = 200000,
    isClient = false,
    tokenPrefix = 'Bearer ',
    tokenKey = 'token',
    getTokenFn = null,
    clearAuthFn = null,
    redirectOnAuthFail = true,
    redirectPath = '/login',
    debug = false,
  } = options

  // 使用提供的函数或默认函数
  const getTokenFunction = getTokenFn || (() => localStorage.getItem(tokenKey))
  const clearAuthFunction = clearAuthFn || (() => localStorage.removeItem(tokenKey))

  /**
   * 日志函数
   */
  const log = {
    info: (...args) => {
      if (debug) console.log(`[${isClient ? 'Client' : 'Admin'}] Fetch:`, ...args)
    },
    error: (...args) => console.error(`[${isClient ? 'Client' : 'Admin'}] Fetch:`, ...args),
    warn: (...args) => console.warn(`[${isClient ? 'Client' : 'Admin'}] Fetch:`, ...args),
  }

  return async (url, options = {}) => {
    try {
      const token = getTokenFunction()
      log.info('发送请求:', url)

      // 添加时间戳避免缓存
      const separator = url.includes('?') ? '&' : '?'
      const urlWithTimestamp = `${url}${separator}_t=${Date.now()}`

      const controller = new AbortController()
      const timeoutId = setTimeout(() => controller.abort('timeout'), timeout)

      // 处理URL
      let fullUrl
      if (urlWithTimestamp.startsWith('http')) {
        fullUrl = urlWithTimestamp
      } else {
        // 当baseURL为空时，直接使用url（相对路径）
        if (!baseURL) {
          fullUrl = urlWithTimestamp.startsWith('/') ? urlWithTimestamp : `/${urlWithTimestamp}`
        }
        // 处理baseURL末尾和url开头可能都有斜杠的情况
        else if (baseURL.endsWith('/') && urlWithTimestamp.startsWith('/')) {
          fullUrl = `${baseURL}${urlWithTimestamp.substring(1)}` // 移除url开头的斜杠
        } else if (!baseURL.endsWith('/') && !urlWithTimestamp.startsWith('/')) {
          fullUrl = `${baseURL}/${urlWithTimestamp}` // 添加中间的斜杠
        } else {
          fullUrl = `${baseURL}${urlWithTimestamp}` // 正常情况，一边有斜杠
        }
      }

      // 处理请求头
      const headers = {
        ...options.headers,
      }

      // 添加token
      if (token) {
        headers['Authorization'] = `${tokenPrefix}${token}`

        try {
          const userInfo = JSON.parse(localStorage.getItem('user_info'))
          if (userInfo && userInfo.username) {
            headers['username'] = userInfo.username
          }
        } catch (e) {
          log.warn('获取用户信息失败', e)
        }
      }

      const response = await fetch(fullUrl, {
        ...options,
        headers,
        signal: controller.signal,
      })

      clearTimeout(timeoutId)

      log.info('接收响应:', fullUrl, response.status)

      // 处理401/403错误
      if (response.status === 401 || response.status === 403) {
        log.warn('Token已失效，将重新登录')
        clearAuthFunction()

        if (redirectOnAuthFail) {
          window.location.href = redirectPath
        }
        throw new Error('Unauthorized')
      }

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }

      return response
    } catch (error) {
      if (error.name === 'AbortError') {
        log.error('请求超时:', url)
        throw new Error('请求超时，请稍后重试')
      }

      log.error('请求错误:', url, error.message)
      throw error
    }
  }
}

// 创建默认的管理端服务实例
const adminService = createRequestInstance({
  useElementUI: true,
  getTokenFn: getToken,
  clearAuthFn: clearAuth,
  routerInstance: router,
  debug: authConfig.DEBUG_ENABLED,
  redirectPath: authConfig.ADMIN_LOGIN_PATH, // 管理端使用管理登录路径
  setupActivityMonitor: true, // 由管理端负责设置活动监听器
})

export default adminService
